/*
 * -------------------------------------------------------------------------------------------------------*
 * SBS Priceboard V2.0
 * Copyright (C) 2008 Unicom Vietnam JSC
 * -------------------------------------------------------------------------------------------------------* 
 * HeadURL: http://192.168.1.4/svn/priceboard/trunk/SBS_PriceboardV2/front-end/end-user/enduser_priceboard/
 * LastChangeBy:
 * LastChangeDate:
 */
package com.unicom.priceboard.data.hose;

import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;

import org.apache.log4j.Logger;

import com.unicom.priceboard.data.OpenPriceParser;
import com.unicom.priceboard.thread.LeThread;
import com.unicom.priceboard.thread.MarketStatusThread;
import com.unicom.priceboard.thread.SecurityThread;
import com.unicom.priceboard.thread.TimerThread;
import com.unicom.priceboard.util.Constants;
import com.unicom.priceboard.util.NumberUtil;
import com.unicom.priceboard.util.Util;
import com.unicom.priceboard.data.vo.FRoomElement;
import com.unicom.priceboard.thread.FroomThread;
import com.unicom.priceboard.data.vo.HoStock;
import com.unicom.priceboard.data.vo.LeElement;
import com.unicom.priceboard.data.vo.SecurityElement;

/**
 * Creation date: Jul 16, 2008
 * @author quan
 */
public class SecurityReader {
	private HoStock tempStock;
	int iTem=0;
	private static final Logger logger = Logger.getLogger(SecurityReader.class);
	public void parsingDatSecurity(String path){
		try{
			int marketState = Integer.parseInt(MarketStatusThread.getCurrentMarketState());
			FileInputStream instrSecurities = new FileInputStream(Util.getCurrentDataPath(path));
			parseSecurityElement(instrSecurities,marketState);
			instrSecurities.close();
		}catch(Exception e){
			logger.debug("not read file: "+e.getMessage());
		}
	}
	private void parseSecurityElement(InputStream is, int marketState) throws IOException{
		DataInputStream input = new DataInputStream(is);
	
		try {
			StringBuffer str;
			while (input.available()>0) {
				SecurityElement record = new SecurityElement();

				// Create a new ByteBuffer to store a record from file
				ByteBuffer buf = ByteBuffer.allocate(221);
				// Set to little endian
				buf.order(ByteOrder.LITTLE_ENDIAN);
				// Get each field from the file and put it to the byte buffer
				buf.putShort(input.readShort()); // Stockno

				for (int i = 0; i < 8; i++)
					buf.put(input.readByte()); // StockSymbol

				buf.put(input.readByte()); // StockType
				buf.putInt(input.readInt()); // Ceiling
				buf.putInt(input.readInt()); // Floor
				buf.putDouble(input.readDouble()); // BigLotValue

				for (int i = 0; i < 25; i++)
					buf.put(input.readByte()); // SecurityElementName

				buf.put(input.readByte()); // SectorNo
				buf.put(input.readByte()); // Designated
				buf.put(input.readByte()); // SUSPENSION
				buf.put(input.readByte()); // Delist
				buf.put(input.readByte()); // HaltResumeFlag
				buf.put(input.readByte()); // SPLIT
				buf.put(input.readByte()); // Benefit
				buf.put(input.readByte()); // Meeting
				buf.put(input.readByte()); // Notice
				buf.put(input.readByte()); // ClientIDRequired
				buf.putShort(input.readShort()); // CouponRate

				for (int i = 0; i < 6; i++)
					buf.put(input.readByte()); // IssueDate

				for (int i = 0; i < 6; i++)
					buf.put(input.readByte()); // MatureDate

				buf.putInt(input.readInt()); // AvrPrice
				buf.putShort(input.readShort()); // ParValue
				buf.put(input.readByte()); // SDCFlag
				buf.putInt(input.readInt()); // PriorClosePrice

				for (int i = 0; i < 6; i++)
					buf.put(input.readByte()); // PriorCloseDate

				buf.putInt(input.readInt()); // ProjectOpen
				buf.putInt(input.readInt()); // OpenPrice
				buf.putInt(input.readInt()); // Last
				buf.putInt(input.readInt()); // LastVol
				buf.putDouble(input.readDouble()); // LastVal
				buf.putInt(input.readInt()); // Highest
				buf.putInt(input.readInt()); // Lowest
				buf.putDouble(input.readDouble()); // Totalshares
				buf.putDouble(input.readDouble()); // TotalValue
				buf.putShort(input.readShort()); // AccumulateDeal
				buf.putShort(input.readShort()); // BigDeal
				buf.putInt(input.readInt()); // BigVolume
				buf.putDouble(input.readDouble()); // BigValue
				buf.putShort(input.readShort()); // OddDeal
				buf.putInt(input.readInt()); // OddVolume
				buf.putDouble(input.readDouble()); // OddValue
				buf.putInt(input.readInt()); // Best1Bid
				buf.putInt(input.readInt()); // Best1BidVolume
				buf.putInt(input.readInt()); // Best2Bid
				buf.putInt(input.readInt()); // Best2BidVolume
				buf.putInt(input.readInt()); // Best3Bid
				buf.putInt(input.readInt()); // Best3BidVolume
				buf.putInt(input.readInt()); // Best1Offer
				buf.putInt(input.readInt()); // Best1OfferVolume
				buf.putInt(input.readInt()); // Best2Offer
				buf.putInt(input.readInt()); // Best2OfferVolume
				buf.putInt(input.readInt()); // Best3Offer
				buf.putInt(input.readInt()); // Best3OfferVolume
				buf.putShort(input.readShort()); // BoardLost

				// Reset position for reading
				buf.flip();
				// Set to big endian
				buf.order(ByteOrder.BIG_ENDIAN);

				// Retrieve data from byte buffer

				record.setStockNo(buf.getShort()); //ma chung khoan dang so

				str = new StringBuffer(); 
				//String symbol;
				for (int i = 0; i < 8; i++)
				str.append((char) buf.get());//stock symbol
			
				record.setSymbolCode(str.toString().trim());// As String * 8
				record.setStockType((char) buf.get());
				record.setCeiling(buf.getInt());
				record.setFloor(buf.getInt());
				record.setBigLotValue(buf.getDouble());

				str = new StringBuffer();
				for (int i = 0; i < 25; i++)
					str.append((char) buf.get());
				record.setSecurityName(str.toString().trim());// As String * 25

				record.setSectorNo((char) buf.get());
				record.setDesignated((char) buf.get());
				record.setSuspension((char) buf.get());
				record.setDelist((char) buf.get());
				record.setHaltResumeFlag((char) buf.get());
				record.setSplit((char) buf.get());
				record.setBenefit((char) buf.get());
				record.setMeeting((char) buf.get());
				record.setNotice((char) buf.get());
				record.setClientIdRequired((char) buf.get());
				record.setCouponRate(buf.getShort());

				str = new StringBuffer();
				for (int i = 0; i < 6; i++)
					str.append((char) buf.get());
				record.setIssueDate(str.toString().trim());// As String * 6

				str = new StringBuffer();
				for (int i = 0; i < 6; i++)
					str.append((char) buf.get());
				record.setMatureDate(str.toString().trim());// As String * 6

				record.setAvrPrice(buf.getInt());
				record.setParValue(buf.getShort());
				record.setSdcFlag((char) buf.get());
				record.setPriorClosePrice(buf.getInt());

				str = new StringBuffer();
				for (int i = 0; i < 6; i++)
					str.append((char) buf.get());
				record.setPriorCloseDate(str.toString().trim());// As String * 6

				record.setProjectOpen(buf.getInt());
				record.setOpenPrice(buf.getInt());
				record.setLast(buf.getInt());
				record.setLastVol(buf.getInt());
				record.setLastVal(buf.getDouble());
				record.setHighest(buf.getInt());
				record.setLowest(buf.getInt());
				record.setTotalShares(buf.getDouble());
				record.setTotalValue(buf.getDouble());
				record.setAccumulateDeal(buf.getShort());
				record.setBigDeal(buf.getShort());
				record.setBigVolume(buf.getInt());
				record.setBigValue(buf.getDouble());
				record.setOddDeal(buf.getShort());
				record.setOddVolume(buf.getInt());
				record.setOddValue(buf.getDouble());
				record.setBest1Bid(buf.getInt());
				record.setBest1BidVolume(buf.getInt());
				record.setBest2Bid(buf.getInt());
				record.setBest2BidVolume(buf.getInt());
				record.setBest3Bid(buf.getInt());
				record.setBest3BidVolume(buf.getInt());
				record.setBest1Offer(buf.getInt());
				record.setBest1OfferVolume(buf.getInt());
				record.setBest2Offer(buf.getInt());
				record.setBest2OfferVolume(buf.getInt());
				record.setBest3Offer(buf.getInt());
				record.setBest3OfferVolume(buf.getInt());
				record.setBoardLost(buf.getShort());//this could be removed in the future
				
				//check list stock(new stock will add to list symbol)
				if(!SecurityThread.lstSymbols.containsKey(record.getStockNo()))
					SecurityThread.lstSymbols.put(record.getStockNo(), record.getSymbolCode());
				
				if(marketState>=Integer.parseInt(Constants.MARKET_STATE_CONTINOUS_SESSION)
					&& marketState!=Integer.valueOf(Constants.MARKET_STATE_PRE_OPEN)) {					
					LeElement oLe_vol1 = LeThread.T1_lastest_object.get(record.getStockNo());					
					if(OpenPriceParser.mapOpenPrice.size()!=0){
						if(OpenPriceParser.mapOpenPrice.get(record.getSymbolCode())!=null) {	
							int price=OpenPriceParser.mapOpenPrice.get(record.getSymbolCode()).getOpenPrice();
						 	record.setOpenPrice(price);
						 }
					}					
					record.setPriceOne(record.getOpenPrice());					
					if(oLe_vol1!=null && record.getPriceOne().intValue()!=0)//==oLe_vol1.getPrice())
						record.setVolOne(oLe_vol1.getAccumulatedVol());
				}			
				if(marketState==Integer.parseInt(Constants.MARKET_STATE_OPEN_SESSION) || 
				   marketState==Integer.parseInt(Constants.MARKET_STATE_CLOSE_SESSION)){
					record.setLast(record.getProjectOpen());
					record.setLastVol(0);
				}			
				if(marketState>Integer.parseInt(Constants.MARKET_STATE_CONTINOUS_SESSION)&&marketState!=Integer.valueOf(Constants.MARKET_STATE_PRE_OPEN)) {
					LeElement oLe = LeThread.T2_lastest_object.get(record.getStockNo());
					if(oLe!=null) {
						record.setVolTwo( oLe.getAccumulatedVol());
						record.setPriceTwo(oLe.getPrice());
					}
				}// end session
				
				//if today is sunday and saturday
				if(TimerThread.CURRENT_DAY_OF_WEEK==1||TimerThread.CURRENT_DAY_OF_WEEK==7){	
					//set vol and price one
					if(OpenPriceParser.mapOpenPrice.size()!=0){
						if(OpenPriceParser.mapOpenPrice.get(record.getSymbolCode())!=null) {
							int price=OpenPriceParser.mapOpenPrice.get(record.getSymbolCode()).getOpenPrice();
							record.setOpenPrice(price);
						}
					}					
					record.setPriceOne(record.getOpenPrice());
					LeElement oLe_vol1 = LeThread.T1_lastest_object.get(record.getStockNo());
					if(oLe_vol1!=null && record.getPriceOne().intValue()!=0) {
						record.setVolOne(oLe_vol1.getAccumulatedVol());						
					}
					//set vol and price two
					LeElement oLe = LeThread.T2_lastest_object.get(record.getStockNo());
					if(oLe!=null) {
						record.setVolTwo( oLe.getAccumulatedVol());
						record.setPriceTwo(oLe.getPrice());
					}
				}
				
				record.setChange(record.getLast()-record.getPriorClosePrice());
				
				//new hostock				
				tempStock=new HoStock();
				tempStock.setOpenPrice(String.valueOf(record.getOpenPrice()));
				tempStock.setSymbol_code(record.getSymbolCode());
				tempStock.setStockType(record.getStockType());
				
				iTem = record.getPriorClosePrice() % 100;
				if(OpenPriceParser.mapOpenPrice.size()!=0){
					String symbol=record.getSymbolCode();
					if(OpenPriceParser.mapOpenPrice.get(symbol)!=null) {
						record.setCeiling(OpenPriceParser.mapOpenPrice.get(symbol).getCeiling());
						record.setFloor(OpenPriceParser.mapOpenPrice.get(symbol).getFloor());
						record.setPriorClosePrice(OpenPriceParser.mapOpenPrice.get(symbol).getPriorClosePrice());
					}
				}
				if (iTem != 0)
				    tempStock.setPriorClosePrice(String.valueOf(((double)record.getPriorClosePrice())/100).toString());
				else
					tempStock.setPriorClosePrice(String.valueOf(record.getPriorClosePrice()/100));
				
				//ceiling
				double spare = (double)record.getCeiling() % 100;
				if (spare > 0) {
					Double c = new Double(record.getCeiling());
					tempStock.setCeiling(String.valueOf(c.doubleValue()/100));
				}
				else
					tempStock.setCeiling(String.valueOf(record.getCeiling()/100));
				
				//floor
				spare = record.getFloor() % 100;
				if (spare > 0) {
					Double f = new Double(record.getFloor());
					tempStock.setFloor(String.valueOf(f.doubleValue()/100));
				}
				else
				 tempStock.setFloor(String.valueOf(record.getFloor()/100));
				
				//price
				iTem = record.getLast() % 100;
				if (iTem != 0)
					tempStock.setPrice(NumberUtil.formatNumber(((double)record.getLast())/100));
				else
					tempStock.setPrice(NumberUtil.formatLong(record.getLast()/100));
				
				//LastVolume, value
				tempStock.setVol(NumberUtil.formatLong(record.getLastVol()));
				tempStock.setTotalTradingValue(NumberUtil.formatNumber(record.getLastVal()));
				//change
				if(record.getLast()!=0 && record.getLast()!=null) {
					int dTemp = record.getLast() - record.getPriorClosePrice();
					tempStock.setChange(NumberUtil.formatNumber((double)dTemp /100));
				} else {
					tempStock.setChange("0");
				}
				double refPrice=Double.parseDouble(tempStock.getPriorClosePrice());
				if(refPrice != 0){
					tempStock.setShare_Dividend("0");
					double ceil=(double)record.getCeiling()/100;
					double floor =(double)record.getFloor()/100;
					if(refPrice > ceil || refPrice < floor) {
						double newRefPrice = ((record.getCeiling()+record.getFloor())/2);
						tempStock.setShare_Dividend("1");
						
						double changeNew=record.getLast()-newRefPrice; 
						tempStock.setChange(NumberUtil.oneDigitAfterDecimalPoint(changeNew/100));
					}
				}
				
				//priceOne
				iTem = record.getPriceOne() % 100;
				if (iTem != 0)
					tempStock.setPriceOne(String.valueOf(((double)record.getPriceOne())/100));
					else
					tempStock.setPriceOne(String.valueOf(record.getPriceOne()/100));
				//volOne
				tempStock.setVolOne(NumberUtil.formatLong((record.getVolOne())));
				
				//priceTwo
				iTem = record.getPriceTwo() % 100;
				if (iTem != 0)
					tempStock.setPriceTwo(NumberUtil.formatNumber(((double)record.getPriceTwo())/100));
				else
					tempStock.setPriceTwo(NumberUtil.formatLong(record.getPriceTwo()/100));
				//volTwo	
				tempStock.setVolTwo(NumberUtil.formatLong(record.getVolTwo()));
				
				//best3Bid
				iTem = record.getBest3Bid() % 100;
				if (iTem != 0)
					tempStock.setBest3Bid(NumberUtil.formatNumber(((double)record.getBest3Bid())/100));
				else
					tempStock.setBest3Bid(NumberUtil.formatLong(record.getBest3Bid()/100));
				//Best3bidVolume	
				tempStock.setBest3BidVolume(NumberUtil.formatLong(record.getBest3BidVolume()));
				
				//best2Bid
				iTem = record.getBest2Bid() % 100;
				if (iTem != 0)
					tempStock.setBest2Bid(NumberUtil.formatNumber(((double)record.getBest2Bid())/100));
				else
					tempStock.setBest2Bid(NumberUtil.formatLong(record.getBest2Bid()/100));
				//Best2BidVolume	
				tempStock.setBest2BidVolume(NumberUtil.formatLong(record.getBest2BidVolume()));
				
				//best1Bid
				if(record.getBest1Bid()==0 && record.getBest1BidVolume()!=0){
					if(marketState==Integer.parseInt(Constants.MARKET_STATE_OPEN_SESSION))
						tempStock.setBest1Bid("ATO");
					else if(marketState==Integer.parseInt(Constants.MARKET_STATE_CONTINOUS_SESSION))
						tempStock.setBest1Bid("0");
					else if(marketState==Integer.parseInt(Constants.MARKET_STATE_CLOSE_SESSION))
						tempStock.setBest1Bid("ATC");
					else
						tempStock.setBest1Bid("0");
				}else{
					iTem = record.getBest1Bid() % 100;
					if (iTem != 0)
						tempStock.setBest1Bid(NumberUtil.formatNumber(((double)record.getBest1Bid())/100));
					else
						tempStock.setBest1Bid(NumberUtil.formatLong(record.getBest1Bid()/100));
					}
				tempStock.setBest1BidVolume(NumberUtil.formatLong(record.getBest1BidVolume()));
				
				//best1Offer
				if(record.getBest1Offer()==0 && record.getBest1OfferVolume()!=0) {
					if(marketState==Integer.parseInt(Constants.MARKET_STATE_OPEN_SESSION))
						tempStock.setBest1Offer("ATO");
					else if(marketState==Integer.parseInt(Constants.MARKET_STATE_CONTINOUS_SESSION))
						tempStock.setBest1Offer("0");
					else if(marketState==Integer.parseInt(Constants.MARKET_STATE_CLOSE_SESSION))
						tempStock.setBest1Offer("ATC");
					else
						tempStock.setBest1Offer("0");
				}else{
					iTem = record.getBest1Offer() % 100;
					if (iTem != 0)
						tempStock.setBest1Offer(NumberUtil.formatNumber(((double)record.getBest1Offer())/100));
					else
						tempStock.setBest1Offer(NumberUtil.formatLong(record.getBest1Offer()/100));
					}
				//best1OfferVolume
				tempStock.setBest1OfferVolume(NumberUtil.formatLong(record.getBest1OfferVolume()));
				
				//best2Offer
				iTem = record.getBest2Offer() % 100;
				if (iTem != 0)
					tempStock.setBest2Offer(NumberUtil.formatNumber(((double)record.getBest2Offer())/100));
				else
					tempStock.setBest2Offer(NumberUtil.formatLong(record.getBest2Offer()/100));
				//Best2OfferVolume
				tempStock.setBest2OfferVolume(NumberUtil.formatLong(record.getBest2OfferVolume()));
				
				//best3Offer
				iTem = record.getBest3Offer() % 100;
				if (iTem != 0)
					tempStock.setBest3Offer(NumberUtil.formatNumber(((double)record.getBest3Offer())/100));
				else
					tempStock.setBest3Offer(NumberUtil.formatLong(record.getBest3Offer()/100));
				//Best3OfferVolume			
				tempStock.setBest3OfferVolume(NumberUtil.formatLong(record.getBest3OfferVolume()));
				
				//Highest
				iTem = record.getHighest() % 100;
				if (iTem != 0)
					tempStock.setHighest_price(String.valueOf(((double)record.getHighest())/100));
				else
					tempStock.setHighest_price(String.valueOf(record.getHighest()/100));
				
				//Lowest
				iTem = record.getLowest() % 100;
				if (iTem != 0)
					tempStock.setLowest_price(String.valueOf(((double)record.getLowest())/100));
				else
					tempStock.setLowest_price(String.valueOf(record.getLowest()/100));
				
				//SecurityName
				tempStock.setStock_name(record.getSecurityName().replaceAll("&", "-"));
				
				//Froom
				FRoomElement frElement= FroomThread.lstFRoom.get(new Integer(record.getStockNo()));
				if(frElement!=null){
					spare = frElement.getCurrentRoom()%1000;					
					tempStock.setF_room(NumberUtil.formatTwoDigit(String.valueOf((frElement.getTotalRoom() - frElement.getCurrentRoom())/1000)));
				}else
					tempStock.setF_room("0");
				
				//add trading room
				if(TimerThread.CURRENT_TIME>700&&TimerThread.CURRENT_TIME<900){
					tempStock.setTradingRoom("0");
				}else {
					FRoomElement tradeElement= FroomThread.oldFRoom.get(new Integer(record.getStockNo()));
					if(tradeElement!=null&& frElement!=null){
						double pare;
						pare=(NumberUtil.formatdouble(tradeElement.getCurrentRoom()/1000))-(NumberUtil.formatdouble(frElement.getCurrentRoom()/1000));
						if(pare>0)
							tempStock.setTradingRoom(NumberUtil.formatOneDigit(String.valueOf(pare)));
						else 
							tempStock.setTradingRoom("0");
					}else 
						tempStock.setTradingRoom("0");
				}
				
				//adding to the symbol list
//				if(record.getStockType().equals('S') || record.getStockType().equals('U') ||
//					record.getStockType().equals('s') || record.getStockType().equals('u')) { 
				//Add all to symbol list (include stock, bond and fund certificate)
				if (true) {	
					if(SecurityThread.timeWrite) {
						//change to session 3 write file openprice.xml
						SecurityThread.openPrice.add(record);
					}
					
					HoStock stockInList = SecurityThread.currentStockList.get(tempStock.getSymbol_code());										
					long vol2=Long.parseLong(tempStock.getVolTwo().replaceAll(",",""));
				    long vol1=Long.parseLong(tempStock.getVolOne().replaceAll(",",""));
				   	if((vol2-vol1)==0){
				   		tempStock.setPriceTwo("0");
				   		tempStock.setVolTwo("0");
				   	}
				   	//check new stock
					if(stockInList==null ||!tempStock.equals(stockInList)){
						String symbol =tempStock.getSymbol_code();
						double curchange=Double.valueOf(tempStock.getChange());//record.getChange();
						if(refPrice!=0) {
							double pctChange=0;
							if(curchange!=0)
								pctChange=(curchange/refPrice)*100;
								tempStock.setPct_change(NumberUtil.formatdouble(pctChange));
						}else{
							curchange=0;
							tempStock.setChange("0");
							tempStock.setPct_change(0.0);
						}
						 if(tempStock.getPrice().equals("0")){
							 tempStock.setChange("0");
						 }
						 
 					   	//add new sock to currentStocklist
						SecurityThread.currentStockList.put(symbol,tempStock);
						SecurityThread.mpStockNo.put(record.getStockNo(), symbol);
					}										
				}
			}//end while
		} catch (Exception ex) {
				System.out.println(ex);
		}

	}
}
